﻿/*
 * (c) Stefan Bojarovski 2010
 * */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASTBuilder
{
    class ForNode : NodesCollection, ITreeNode
    {
        private LexemeType lexType = LexemeType.FOR_OPERATOR;
        private ITreeNode Counter; //Identifier
        private ITreeNode Step;
        private ITreeNode Condition; // Boolean expression
        private ITreeNode Body;

        public ForNode(ITreeNode initExpr, ITreeNode stepExpr, ITreeNode boolExpr, ITreeNode listStatements)
        {
            Counter = initExpr;
            Step = stepExpr;
            Condition = boolExpr;
            Body = listStatements;
        }
        public LexemeType getLexemeType()
        {
            return lexType;
        }
        public void printNode(String parentLevel, StreamWriter someStream)
        {
            someStream.WriteLine(parentLevel + " " + "For Operator: ");
            someStream.WriteLine(parentLevel + " " + "Counter: ");
            Counter.printNode(parentLevel, someStream);
            someStream.WriteLine(parentLevel + " " + "Step: ");
            Step.printNode(parentLevel, someStream);
            someStream.WriteLine(parentLevel + " " + "Condition: ");
            Condition.printNode(parentLevel, someStream);
            someStream.WriteLine(parentLevel + " " + "Body: ");
            Body.printNode(parentLevel, someStream);
        }
        public List<Command> evalNode(ref Direction next,
                                        ref Dictionary<String, Pair<IdentifierType, object>> Environment)
        {
            List<Command> result = new List<Command>();
            if (next != Direction.JUMP)
            {
                Command init = Counter.evalNode(ref next, ref Environment)[0];
                Command step = Step.evalNode(ref next, ref Environment)[0];
                Command condition = Condition.evalNode(ref next, ref Environment)[0];
                result = Body.evalNode(ref next, ref Environment);

                while ((bool)condition.getIdValue())
                {
                    List<Command> singleStep = Body.evalNode(ref next, ref Environment);
                    foreach (Command com in singleStep)
                    {
                        result.Add(com);
                    }
                    step = Step.evalNode(ref next, ref Environment)[0];
                    condition = Condition.evalNode(ref next, ref Environment)[0];
                }
                return result;
            }
            else
            {
                result.Add(new Command(CommandType.VOID, null, null));
                return result;
            }
        }
    }
}
